use eframe::egui::{self, pos2, vec2, Color32, Rect, Stroke, StrokeKind};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

// 可视化编程节点类型
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum NodeType {
    Input,
    Output,
    Function,
    Conditional,
    Loop,
    Variable,
    KernelConfig,
    BootFunction,
    LogFunction,
    IoFunction,
}

// 连接点
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Port {
    pub id: String,
    pub name: String,
    pub is_input: bool,
    pub node_id: String,
    pub position: (f32, f32),
}

// 连接线
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Connection {
    pub id: String,
    pub from_port_id: String,
    pub to_port_id: String,
    pub from_node_id: String,
    pub to_node_id: String,
}

// 节点数据
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct NodeData {
    pub node_type: NodeType,
    pub parameters: HashMap<String, String>,
    pub code_template: Option<String>,
}

// 可视化节点
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct VisualNode {
    pub id: String,
    pub title: String,
    pub position: (f32, f32),
    pub size: (f32, f32),
    pub data: NodeData,
    pub ports: Vec<Port>,
    pub selected: bool,
}

// 可视化编程图
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct VisualProgram {
    pub nodes: HashMap<String, VisualNode>,
    pub connections: HashMap<String, Connection>,
    pub selected_node: Option<String>,
    pub selected_connection: Option<String>,
    pub dragging_node: Option<String>,
    pub connecting_from: Option<(String, String)>, // (node_id, port_id)
}

impl Default for VisualProgram {
    fn default() -> Self {
        Self {
            nodes: HashMap::new(),
            connections: HashMap::new(),
            selected_node: None,
            selected_connection: None,
            dragging_node: None,
            connecting_from: None,
        }
    }
}

impl VisualProgram {
    // 创建新节点
    pub fn create_node(&mut self, node_type: NodeType, position: (f32, f32)) -> String {
        let node_id = format!("node_{}", self.nodes.len());
        let title = match node_type {
            NodeType::Input => "输入",
            NodeType::Output => "输出",
            NodeType::Function => "函数",
            NodeType::Conditional => "条件",
            NodeType::Loop => "循环",
            NodeType::Variable => "变量",
            NodeType::KernelConfig => "内核配置",
            NodeType::BootFunction => "启动函数",
            NodeType::LogFunction => "日志函数",
            NodeType::IoFunction => "IO函数",
        };
        
        let mut parameters = HashMap::new();
        let mut code_template = None;
        
        // 根据节点类型设置默认参数和代码模板
        match node_type {
            NodeType::KernelConfig => {
                parameters.insert("kernel_type".to_string(), "main".to_string());
                parameters.insert("cpu_cores".to_string(), "2".to_string());
                parameters.insert("memory_mb".to_string(), "512".to_string());
            },
            NodeType::BootFunction => {
                code_template = Some(r#"boot.启动(配置)"#.to_string());
            },
            NodeType::LogFunction => {
                parameters.insert("message".to_string(), "系统启动完成".to_string());
                code_template = Some(r#"日志.信息("[Chym] {}".format(message))"#.to_string());
            },
            NodeType::IoFunction => {
                parameters.insert("message".to_string(), "chym".to_string());
                code_template = Some(r#"io.输出("{}".format(message))"#.to_string());
            },
            _ => {},
        }
        
        // 创建端口
        let mut ports = Vec::new();
        match node_type {
            NodeType::Input => {
                ports.push(Port {
                    id: format!("port_{}_{}_out", node_id, ports.len()),
                    name: "输出".to_string(),
                    is_input: false,
                    node_id: node_id.clone(),
                    position: (180.0, 30.0),
                });
            },
            NodeType::Output => {
                ports.push(Port {
                    id: format!("port_{}_{}_in", node_id, ports.len()),
                    name: "输入".to_string(),
                    is_input: true,
                    node_id: node_id.clone(),
                    position: (0.0, 30.0),
                });
            },
            NodeType::KernelConfig => {
                ports.push(Port {
                    id: format!("port_{}_{}_out", node_id, ports.len()),
                    name: "配置".to_string(),
                    is_input: false,
                    node_id: node_id.clone(),
                    position: (180.0, 30.0),
                });
            },
            NodeType::BootFunction => {
                ports.push(Port {
                    id: format!("port_{}_{}_in", node_id, ports.len()),
                    name: "配置".to_string(),
                    is_input: true,
                    node_id: node_id.clone(),
                    position: (0.0, 20.0),
                });
                ports.push(Port {
                    id: format!("port_{}_{}_out", node_id, ports.len()),
                    name: "结果".to_string(),
                    is_input: false,
                    node_id: node_id.clone(),
                    position: (180.0, 20.0),
                });
            },
            NodeType::LogFunction => {
                ports.push(Port {
                    id: format!("port_{}_{}_in", node_id, ports.len()),
                    name: "输入".to_string(),
                    is_input: true,
                    node_id: node_id.clone(),
                    position: (0.0, 30.0),
                });
            },
            NodeType::IoFunction => {
                ports.push(Port {
                    id: format!("port_{}_{}_in", node_id, ports.len()),
                    name: "输入".to_string(),
                    is_input: true,
                    node_id: node_id.clone(),
                    position: (0.0, 30.0),
                });
            },
            _ => {},
        }
        
        let node = VisualNode {
            id: node_id.clone(),
            title: title.to_string(),
            position,
            size: (200.0, 80.0),
            data: NodeData {
                node_type,
                parameters,
                code_template,
            },
            ports,
            selected: false,
        };
        
        self.nodes.insert(node_id.clone(), node);
        self.selected_node = Some(node_id.clone());
        
        node_id
    }
    
    // 删除节点
    pub fn delete_node(&mut self, node_id: &str) {
        // 删除所有与该节点相关的连接
        let connections_to_delete: Vec<String> = self.connections.values()
            .filter(|conn| conn.from_node_id == node_id || conn.to_node_id == node_id)
            .map(|conn| conn.id.clone())
            .collect();
        
        for conn_id in connections_to_delete {
            self.connections.remove(&conn_id);
        }
        
        // 删除节点
        self.nodes.remove(node_id);
        
        // 更新选择状态
        if self.selected_node.as_deref() == Some(node_id) {
            self.selected_node = None;
        }
        if self.dragging_node.as_deref() == Some(node_id) {
            self.dragging_node = None;
        }
    }
    
    // 创建连接
    pub fn create_connection(&mut self, from_node_id: &str, from_port_id: &str, to_node_id: &str, to_port_id: &str) -> Option<String> {
        // 检查端口是否存在
        let from_node = self.nodes.get(from_node_id)?;
        let to_node = self.nodes.get(to_node_id)?;
        
        let from_port = from_node.ports.iter().find(|p| p.id == *from_port_id)?;
        let to_port = to_node.ports.iter().find(|p| p.id == *to_port_id)?;
        
        // 检查连接方向是否正确
        if from_port.is_input || !to_port.is_input {
            return None;
        }
        
        // 创建连接
        let conn_id = format!("conn_{}", self.connections.len());
        let connection = Connection {
            id: conn_id.clone(),
            from_port_id: from_port_id.to_string(),
            to_port_id: to_port_id.to_string(),
            from_node_id: from_node_id.to_string(),
            to_node_id: to_node_id.to_string(),
        };
        
        self.connections.insert(conn_id.clone(), connection);
        Some(conn_id)
    }
    
    // 删除连接
    pub fn delete_connection(&mut self, conn_id: &str) {
        self.connections.remove(conn_id);
        
        // 更新选择状态
        if self.selected_connection.as_deref() == Some(conn_id) {
            self.selected_connection = None;
        }
    }
    
    // 渲染可视化编程界面
    pub fn render(&mut self, ui: &mut egui::Ui, painter: &egui::Painter) {
        let rect = ui.max_rect();
        
        // 渲染背景网格
        self.render_background(painter, rect);
        
        // 渲染连接线
        self.render_connections(painter);
        
        // 渲染节点
        self.render_nodes(ui, painter);
        
        // 处理连接创建
        self.handle_connection_creation(ui, painter);
        
        // 处理选择和拖拽
        self.handle_selection_and_drag(ui);
    }
    
    // 渲染背景网格（重命名为render_background）
    pub fn render_background(&self, painter: &egui::Painter, rect: Rect) {
        let grid_size = 20.0;
        let color = Color32::from_gray(200);
        let stroke = Stroke::new(0.5, color);
        
        // 绘制垂直线
        for x in (rect.left() as i32..=rect.right() as i32).step_by((grid_size as i32).try_into().unwrap()) {
            painter.line_segment(
                [pos2(x as f32, rect.top()), pos2(x as f32, rect.bottom())],
                stroke,
            );
        }
        
        // 绘制水平线
        for y in (rect.top() as i32..=rect.bottom() as i32).step_by((grid_size as i32).try_into().unwrap()) {
            painter.line_segment(
                [pos2(rect.left(), y as f32), pos2(rect.right(), y as f32)],
                stroke,
            );
        }
    }
    
    // 渲染连接线（修改为pub）
    pub fn render_connections(&self, painter: &egui::Painter) {
        for connection in self.connections.values() {
            // 获取起始端口位置
            let from_node = self.nodes.get(&connection.from_node_id).unwrap();
            let from_port = from_node.ports.iter()
                .find(|p| p.id == connection.from_port_id).unwrap();
            let from_pos = pos2(
                from_node.position.0 + from_port.position.0,
                from_node.position.1 + from_port.position.1,
            );
            
            // 获取目标端口位置
            let to_node = self.nodes.get(&connection.to_node_id).unwrap();
            let to_port = to_node.ports.iter()
                .find(|p| p.id == connection.to_port_id).unwrap();
            let to_pos = pos2(
                to_node.position.0 + to_port.position.0,
                to_node.position.1 + to_port.position.1,
            );
            
            // 绘制连接线
            let color = if Some(&connection.id) == self.selected_connection.as_ref() {
                Color32::BLUE
            } else {
                Color32::GRAY
            };
            
            painter.line_segment([from_pos, to_pos], Stroke::new(2.0, color));
            
            // 绘制箭头
            let angle = (to_pos.y - from_pos.y).atan2(to_pos.x - from_pos.x);
            let arrow_size = 10.0;
            
            painter.line_segment(
                [
                    to_pos,
                    pos2(
                        to_pos.x - arrow_size * angle.cos() - arrow_size * angle.sin(),
                        to_pos.y - arrow_size * angle.sin() + arrow_size * angle.cos(),
                    ),
                ],
                Stroke::new(2.0, color),
            );
            
            painter.line_segment(
                [
                    to_pos,
                    pos2(
                        to_pos.x - arrow_size * angle.cos() + arrow_size * angle.sin(),
                        to_pos.y - arrow_size * angle.sin() - arrow_size * angle.cos(),
                    ),
                ],
                Stroke::new(2.0, color),
            );
        }
    }
    
    // 渲染节点（修改为pub）
    pub fn render_nodes(&self, ui: &mut egui::Ui, painter: &egui::Painter) {
        for node in self.nodes.values() {
            let rect = Rect::from_min_size(
                pos2(node.position.0, node.position.1),
                vec2(node.size.0, node.size.1),
            );
            
            // 绘制节点背景
            let color = if node.selected {
                Color32::from_rgb(200, 220, 255)
            } else {
                Color32::WHITE
            };
            
            painter.rect(
                        rect,
                        5.0,
                        color,
                        Stroke::new(2.0, Color32::GRAY),
                        StrokeKind::Inside
                    );
            
            // 绘制节点标题
            painter.text(
                pos2(node.position.0 + 10.0, node.position.1 + 20.0),
                egui::Align2::LEFT_TOP,
                &node.title,
                egui::FontId::proportional(16.0),
                Color32::BLACK,
            );
            
            // 绘制端口
            for port in &node.ports {
                let port_pos = pos2(
                    node.position.0 + port.position.0,
                    node.position.1 + port.position.1,
                );
                
                let port_color = if port.is_input {
                    Color32::GREEN
                } else {
                    Color32::RED
                };
                
                painter.circle(port_pos, 5.0, port_color, Stroke::new(1.0, Color32::BLACK));
            }
        }
    }
    
    // 处理连接创建（修改为pub）
    pub fn handle_connection_creation(&mut self, ui: &mut egui::Ui, painter: &egui::Painter) {
        if let Some((from_node_id, from_port_id)) = &self.connecting_from {
            let from_node = self.nodes.get(from_node_id).unwrap();
            let from_port = from_node.ports.iter()
                .find(|p| p.id == *from_port_id).unwrap();
            let from_pos = pos2(
                from_node.position.0 + from_port.position.0,
                from_node.position.1 + from_port.position.1,
            );
            
            let mouse_pos = ui.input(|i| i.pointer.interact_pos().unwrap_or(from_pos));
            
            // 绘制临时连接线
            painter.line_segment([from_pos, mouse_pos], Stroke::new(2.0, Color32::BLUE));
        }
    }
    
    // 处理选择和拖拽（修改为pub）
    pub fn handle_selection_and_drag(&mut self, ui: &mut egui::Ui) {
        let response = ui.interact(ui.max_rect(), ui.id().with("visual_program"), egui::Sense::drag());
        
        let pointer = ui.input(|i| i.pointer.clone());
        
        if pointer.secondary_clicked() {
            // 右键点击，取消选择
            self.selected_node = None;
            self.selected_connection = None;
        }
        
        if let Some(mouse_pos) = pointer.interact_pos() {
            // 检查是否点击了端口
            if pointer.primary_clicked() {
                let mut port_clicked = false;
                let mut connection_info = None;
                
                // 第一阶段：找到被点击的端口
                for node in self.nodes.values() {
                    for port in &node.ports {
                        let port_pos = pos2(
                            node.position.0 + port.position.0,
                            node.position.1 + port.position.1,
                        );
                        
                        // 明确使用egui::Vec2进行类型推断
                        let distance = egui::Vec2::new(
                            mouse_pos.x - port_pos.x,
                            mouse_pos.y - port_pos.y
                        );
                        if distance.length() < 10.0 {
                            port_clicked = true;
                            if !port.is_input {
                                // 从输出端口开始连接
                                self.connecting_from = Some((node.id.clone(), port.id.clone()));
                            } else if let Some((from_node_id, from_port_id)) = &self.connecting_from {
                                // 保存连接信息，稍后创建连接
                                connection_info = Some((
                                    from_node_id.clone(),
                                    from_port_id.clone(),
                                    node.id.clone(),
                                    port.id.clone()
                                ));
                            }
                            break;
                        }
                    }
                    if port_clicked {
                        break;
                    }
                }
                
                // 第二阶段：创建连接
                if let Some((from_node_id, from_port_id, to_node_id, to_port_id)) = connection_info {
                    self.create_connection(&from_node_id, &from_port_id, &to_node_id, &to_port_id);
                    self.connecting_from = None;
                }
                
                if port_clicked {
                    return;
                }
            }
            
            // 检查是否点击了节点
            if pointer.primary_clicked() {
                let mut clicked_node_id = None;
                
                // 第一阶段：找到被点击的节点
                for node in self.nodes.values() {
                    let rect = Rect::from_min_size(
                        pos2(node.position.0, node.position.1),
                        vec2(node.size.0, node.size.1),
                    );
                    
                    if rect.contains(mouse_pos) {
                        clicked_node_id = Some(node.id.clone());
                        break;
                    }
                }
                
                // 第二阶段：更新选择状态
                if let Some(node_id) = clicked_node_id {
                    // 取消所有节点的选择
                    for node in self.nodes.values_mut() {
                        node.selected = false;
                    }
                    
                    // 选择当前节点
                    if let Some(node) = self.nodes.get_mut(&node_id) {
                        node.selected = true;
                        self.selected_node = Some(node_id.clone());
                        self.dragging_node = Some(node_id.clone());
                    }
                    return;
                } else {
                    // 点击了空白区域，取消选择
                    for node in self.nodes.values_mut() {
                        node.selected = false;
                    }
                    self.selected_node = None;
                    self.dragging_node = None;
                }
            }
            
            // 处理拖拽
            // 使用primary_down()检测拖拽状态，这是egui 0.33.2中的常用方法
            if pointer.primary_down() && self.dragging_node.is_some() {
                let delta = pointer.delta();
                if let Some(node_id) = &self.dragging_node {
                    if let Some(node) = self.nodes.get_mut(node_id) {
                        node.position.0 += delta.x;
                        node.position.1 += delta.y;
                    }
                }
            } else {
                self.dragging_node = None;
            }
        }
    }
    
    // 生成Chym代码
    pub fn generate_chym_code(&self) -> String {
        let mut code = String::new();
        
        // 添加文件头部
        code.push_str("#!chim\n");
        code.push_str("// Chym 内核配置文件 (由 OS Design Studio 可视化编程工具自动生成)\n\n");
        code.push_str("系统\n");
        code.push_str("模块 Chym\n\n");
        code.push_str("import 内核::src::system::parker::启动内核 as boot\n");
        code.push_str("import 输入输出::serial as io\n");
        code.push_str("import 日志\n\n");
        code.push_str("公共 fn 主():\n");
        
        // 收集内核配置
        let kernel_configs: Vec<&VisualNode> = self.nodes.values()
            .filter(|node| node.data.node_type == NodeType::KernelConfig)
            .collect();
        
        if !kernel_configs.is_empty() {
            code.push_str("    // 使用Parker多内核启动方案\n");
            code.push_str("    配置 = {\n");
            code.push_str("        \"内核\": [\n");
            
            for (i, node) in kernel_configs.iter().enumerate() {
                // 修复临时值生命周期问题：将默认值存储在局部变量中
                let default_kernel_type = "main".to_string();
                let default_cpu_cores = "2".to_string();
                let default_memory_mb = "512".to_string();
                
                let kernel_type = node.data.parameters.get("kernel_type").unwrap_or(&default_kernel_type);
                let cpu_cores = node.data.parameters.get("cpu_cores").unwrap_or(&default_cpu_cores);
                let memory_mb = node.data.parameters.get("memory_mb").unwrap_or(&default_memory_mb);
                
                code.push_str(&format!("            {{\"类型\": \"{}\", \"cpu_cores\": {}, \"memory_mb\": {}}}\n",
                    kernel_type, cpu_cores, memory_mb));
                
                if i < kernel_configs.len() - 1 {
                    code.push_str(",");
                }
            }
            
            code.push_str("        ]\n");
            code.push_str("    }\n");
        }
        
        // 处理其他节点的代码生成
        let boot_nodes: Vec<&VisualNode> = self.nodes.values()
            .filter(|node| node.data.node_type == NodeType::BootFunction)
            .collect();
        
        for node in boot_nodes {
            if let Some(template) = &node.data.code_template {
                code.push_str(&format!("    // {}\n", node.title));
                code.push_str(&format!("    错误信息 = {}\n", template));
            }
        }
        
        // 处理条件判断
        code.push_str("    如果 错误信息:\n");
        code.push_str("        日志.错误(\"[Chym] 启动失败: {}\".format(错误信息));\n");
        code.push_str("        io.输出(\"启动失败: {}\".format(错误信息));\n");
        code.push_str("        返回\n");
        
        // 处理日志和IO函数
        let log_nodes: Vec<&VisualNode> = self.nodes.values()
            .filter(|node| node.data.node_type == NodeType::LogFunction)
            .collect();
        
        let io_nodes: Vec<&VisualNode> = self.nodes.values()
            .filter(|node| node.data.node_type == NodeType::IoFunction)
            .collect();
        
        for node in log_nodes.iter().chain(io_nodes.iter()) {
            if let Some(template) = &node.data.code_template {
                let mut generated_code = template.clone();
                
                // 替换参数
                for (key, value) in &node.data.parameters {
                    generated_code = generated_code.replace(key, value);
                }
                
                code.push_str(&format!("    // {}\n", node.title));
                code.push_str(&format!("    {}\n", generated_code));
            }
        }
        
        code
    }
}